# coding=utf-8
import hashlib
from json import JSONEncoder
import json
from django.contrib.auth.decorators import login_required
from django.db import transaction
from django.db.models.query import QuerySet
from django.http import HttpResponse
from django.shortcuts import render_to_response, redirect
from django.template import RequestContext
import time
from com.kjssoft.common.forms import query_decorator
from com.kjssoft.common.globals import EagleyeAssist
from com.kjssoft.common.views import transform_model_by_id_decorator
from com.kjssoft.eagleye.models import EEUser
from com.kjssoft.eagleye.views import EEUserJsonEncoder
from com.kjssoft.rainbow import LOGGER
from com.kjssoft.rainbow.album.models import RainbowPhotoFrameAlbum
from com.kjssoft.rainbow.consts import PhotoFrameConsts
from com.kjssoft.rainbow.frame.forms import RainbowPhotoFrameForm, RainbowPhotoAddCommentForm
from com.kjssoft.rainbow.frame.models import RainbowPhotoFrame, RainbowPhotoFrameComment
from com.kjssoft.rainbow.label.views import RainbowPhotoFrameLabelJSONEncoder
from com.kjssoft.rainbow.views import response_format_decorator

__author__ = 'Sea'

class RainbowPhotoFrameCommentJsonEncoder(JSONEncoder):
    def default(self, instance):
        if instance:
            if isinstance(instance, RainbowPhotoFrameComment):
                return {
                    'id':instance.id,
                    'comment':instance.comment,
                    'commentator':EEUserJsonEncoder().default(instance.commentator)
                }
            elif isinstance(instance, list) or isinstance(instance, QuerySet):
                instance_json_list = []
                for i in instance :
                    instance_json_list.append(self.default(i))
                return instance_json_list
        return super(RainbowPhotoFrameCommentJsonEncoder, self).default()

def _rainbow_photo_frame_save_or_update(bound_and_valid_form):
    layout = bound_and_valid_form.instance.layout
    data = bound_and_valid_form.cleaned_data
    labels = data.get('labels')
    photos = data.get('photos')
    if PhotoFrameConsts.Layout.SINGLE_PHOTO_PER_FRAME == layout:
        photo_frame_instance_list = []
        photo_frame_instance = bound_and_valid_form.instance
        for photo_cell in photos:
            try:
                md5 = hashlib.md5()
                md5.update(photo_cell.image.uuid)
                md5.update(str(photo_frame_instance.user.id))
                frame = RainbowPhotoFrame.objects.create(
                    user       = photo_frame_instance.user,
                    album      = photo_frame_instance.album,
                    md5        = md5.hexdigest(),
                    subject    = photo_frame_instance.subject,
                    publish_ms = int(time.time()),
                    layout     = layout,
                    status     = photo_frame_instance.status,
                    scope      = photo_frame_instance.scope,
                )
                frame.save()
                frame.photos.add(photo_cell)
                if labels:
                    label_ids = []
                    for label in labels:
                        LOGGER.debug('rainbow photo frame label %s' % label)
                        photo_frame_instance.labels.add(label)
                        label_ids.append(label.id)
                    photo_frame_instance.labels.exclude(id__in = label_ids).delete()
                photo_frame_instance_list.append(frame)
            except Exception as e:
                LOGGER.error(e)
        return photo_frame_instance_list
    photo_frame_instance = bound_and_valid_form.save()
    if labels:
        label_ids = []
        for label in labels:
            LOGGER.debug('rainbow photo frame label %s' % label)
            photo_frame_instance.labels.add(label)
            label_ids.append(label.id)
        photo_frame_instance.labels.exclude(id__in = label_ids).delete()
    else:
        photo_frame_instance.labels.all().delete()
    if photos:
        photo_ids = []
        for photo in photos:
            photo_frame_instance.photos.add(photo)
            photo_ids.append(photo.id)
        photo_frame_instance.photos.exclude(id__in = photo_ids).delete()
    return photo_frame_instance

@login_required(login_url = EagleyeAssist.get_login_url())
@transaction.commit_on_success
@transform_model_by_id_decorator('album_instance', RainbowPhotoFrameAlbum)
def save_view_page(request, album_instance = None):
    if request.POST:
        form = RainbowPhotoFrameForm(request.user, data = request.POST)
        if form.is_bound and form.is_valid():
            photo_instance = _rainbow_photo_frame_save_or_update(form)
            if isinstance(photo_instance, list):
                return redirect('/rainbow/photoframe/list/of/user/%s' % request.user.id)
            return redirect('/rainbow/photoframe/%s/show' % photo_instance.id)
    form = RainbowPhotoFrameForm()
    form['album'].field.queryset = RainbowPhotoFrameAlbum.objects.filter(
        user = request.user
    )
    form['album'].field.initial = album_instance
    return render_to_response(
        'kjs/rainbow/frame/create.html',
        {'form':form},
        context_instance = RequestContext(request)
    )

@transform_model_by_id_decorator('photo_instance', RainbowPhotoFrame)
@response_format_decorator
def show_view_page(request, photo_instance = None):
    if not request.user.is_authenticated():
        if photo_instance.scope != PhotoFrameConsts.Scope.PUBLIC or photo_instance.status != PhotoFrameConsts.Status.VERIFIED:
            return redirect('/rainbow/album/%s/of/user/%s/show' % (photo_instance.album.id, photo_instance.album.user.id))
    if request.response_format == 'sample':
        return render_to_response(
            'kjs/rainbow/frame/show_%s.html' % request.response_format,
            {'photo_instance':photo_instance},
            context_instance = RequestContext(request)
        )
    photo_instance.publish_ms = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(photo_instance.publish_ms))
    return render_to_response(
        'kjs/rainbow/frame/show.html',
        {'photo_instance':photo_instance},
        context_instance = RequestContext(request)
    )

@login_required(login_url = EagleyeAssist.get_login_url())
@transaction.commit_on_success
@transform_model_by_id_decorator('photo_instance', RainbowPhotoFrame)
def edit_view_page(request, photo_instance = None):
    if request.user != photo_instance.user:
        return redirect('/rainbow/photoframe/%s/show' % photo_instance.id)
    if request.POST:
        form = RainbowPhotoFrameForm(request.user, data = request.POST, instance = photo_instance)
        if form.is_bound and form.is_valid():
            photo_instance = _rainbow_photo_frame_save_or_update(form)
            LOGGER.debug('rainbow photo labels %s' % photo_instance.labels.all())
            return redirect('/rainbow/photoframe/%s/show' % photo_instance.id)
    initial = {
        'layout':photo_instance.layout,
        'scope':photo_instance.scope,
        'subject':photo_instance.subject,
        'status':photo_instance.status,
        'description':photo_instance.description,
    }
    labels = photo_instance.labels.all()
    LOGGER.debug('rainbow photo labels %s' % photo_instance.labels.all())
    if labels.count():
        LOGGER.debug('labels %s' % json.dumps(labels, cls=RainbowPhotoFrameLabelJSONEncoder))
        initial['labels'] = json.dumps(labels, cls=RainbowPhotoFrameLabelJSONEncoder)
    form = RainbowPhotoFrameForm(initial=initial)
    form['album'].field.queryset = RainbowPhotoFrameAlbum.objects.filter(
        user = request.user
    )
    form['album'].field.initial = photo_instance.album
    LOGGER.debug('photo frame status %s' % photo_instance.status)
    form['status'].field.initial = photo_instance.status
    return render_to_response(
        'kjs/rainbow/frame/edit.html',
        {
            'photo_instance':photo_instance,
            'form':form
        },
        context_instance = RequestContext(request)
    )

def _get_page_photos(index = 0, scope = 5, photo_list = None):
    count = photo_list.count()
    if index > count - 1:
        photo_list = []
    else:
        end = index + scope
        if end > count:
            end = count
        photo_list = photo_list[index:end]
    return photo_list

@query_decorator(default_index = 0, default_scope = 30)
@response_format_decorator
def list_view_page(request, user_instance = None, album_instance = None):
    index = request.query_params.index
    scope = request.query_params.scope
    is_auth = False
    is_owner = False
    is_auth_owner = False
    if request.user.is_authenticated():
        is_auth = True
    if user_instance:
        if user_instance == request.user:
            is_owner = True
    if album_instance:
        if album_instance.user == request.user:
            is_owner = True
    if is_auth and is_owner:
        is_auth_owner = True
    LOGGER.debug('query photo frames by user instance %s (is auth owner %s), album instance %s' % (
        user_instance,
        is_auth_owner,
        album_instance,
    ))
    photo_list = RainbowPhotoFrame.objects.get_photos(
        user_instance = user_instance,
        is_auth_owner = is_auth_owner,
        album_instance = album_instance
    )
    count = photo_list.count()
    photo_list = _get_page_photos(index, scope, photo_list)
    if 'json' == request.response_format:
        return render_to_response(
            'kjs/rainbow/frame/list_sample.html',
            {
                'user_instance':user_instance,
                'album_instance':album_instance,
                'is_auth_owner':is_auth_owner,
                'photo_list':photo_list,
                'index':index,
                'count':count,
                'scope':scope
            },
            context_instance = RequestContext(request)
        )
    return render_to_response(
        'kjs/rainbow/frame/list.html',
        {
            'user_instance':user_instance,
            'album_instance':album_instance,
            'is_auth_owner':is_auth_owner,
            'photo_list':photo_list,
            'index':index,
            'count':count,
            'scope':scope
        },
        context_instance = RequestContext(request)
    )

@transform_model_by_id_decorator('album_instance', RainbowPhotoFrameAlbum)
def list_in_album_view_page(request, album_instance = None):
    """
    查找相册图片
    """
    LOGGER.debug('=========================%s' % list_in_album_view_page)
    return list_view_page(request, album_instance = album_instance)

@transform_model_by_id_decorator('user_instance', EEUser)
def list_of_user_view_page(request, user_instance = None):
    """
    查找用户图片
    """
    LOGGER.debug('=========================%s' % list_of_user_view_page)
    return list_view_page(request, user_instance)

@login_required(login_url=EagleyeAssist.get_login_url())
@transaction.commit_on_success
@transform_model_by_id_decorator('photo_instance', RainbowPhotoFrame)
@response_format_decorator
def add_comment_view_page(request, photo_instance = None):
    """
    添加图片评论
    """
    if request.POST:
        form = RainbowPhotoAddCommentForm(request.POST)
        if form.is_bound and form.is_valid():
            comment_instance = form.instance
            comment_instance.commentator = request.user
            comment_instance.publish_ms = int(time.time())
            comment_instance.save()
            photo_instance.comments.add(comment_instance)
            if request.response_format == 'json':
                return HttpResponse(json.dumps(comment_instance, cls=RainbowPhotoFrameCommentJsonEncoder), mimetype="text/json")
            return redirect('/rainbow/photoframe/%s/show' % photo_instance.id)
    form = RainbowPhotoAddCommentForm(initial = {})
    return render_to_response(
        'kjs/rainbow/frame/comment/create.html',
        {
            'instance':photo_instance,
            'form':form
         },
        context_instance = RequestContext(request)
    )

@login_required(login_url=EagleyeAssist.get_login_url())
@transaction.commit_on_success
@transform_model_by_id_decorator('photo_instance', RainbowPhotoFrame)
@transform_model_by_id_decorator('comment_instance', RainbowPhotoFrameComment)
@response_format_decorator
def delete_comment_view_page(request, photo_instance = None, comment_instance = None):
    """
    删除图片的评论
    """
    if request.user == comment_instance.commentator:
        photo_instance.comments.remove(comment_instance)
    return redirect('/rainbow/photoframe/%s/show' % photo_instance.id)
